/* Copyright (c) 2001-2008, The HSQL Development Group
 * All rights reserved.
 *
 * Redistribution and use _in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * Redistributions _in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer _in the documentation
 * and/or other materials provided with the distribution.
 *
 * Neither the name of the HSQL Development Group nor the names of its
 * contributors may be used to endorse or promote products derived from this
 * software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */


using System;
using System.Net;
using System.Collections.Generic;
using EffiProz.Core.Persist;

//TODO:  move to here from Server and WebServer the remaining extraneous code
//       dealing primarily with reading/setting properties from files, etc.

/**
 * Assists with Server and WebServer configuration tasks.
 *
 * @author  boucherb@users
 * @version 1.7.2
 * @since 1.7.2
 */
namespace EffiProz.Server
{

    public class ServerConfiguration
    {

        private ServerConfiguration() { }

        /**
         * Retrieves the default port that a Server will try to use _in the
         * abscence of an explicitly specified one, given the specified
         * value for whether or not to use secure sockets.
         *
         * @param protocol the protcol specifier code of the Server
         * @param isTls if true, retrieve the default port when using secure
         *      sockets, else the default port when using plain sockets
         * @return the default port used _in the abscence of an explicit
         *      specification.
         *
         */
        public static int getDefaultPort(int protocol, bool isTls)
        {

            switch (protocol)
            {

                case ServerConstants.SC_PROTOCOL_EFZ:
                    {
                        return isTls ? ServerConstants.SC_DEFAULT_EFZS_SERVER_PORT
                                 : ServerConstants.SC_DEFAULT_EFZ_SERVER_PORT;
                    }
                case ServerConstants.SC_PROTOCOL_HTTP:
                    {
                        return isTls ? ServerConstants.SC_DEFAULT_HTTPS_SERVER_PORT
                                 : ServerConstants.SC_DEFAULT_HTTP_SERVER_PORT;
                    }
               default:
                    {
                        return -1;
                    }
            }
        }

        /**
         * Retrieves a new HsqlProperties object, if possible, loaded from the
         * specified file.
         *
         * @param path the file's path, without the .properties extention
         *      (which is added automatically)
         * @return a new properties object loaded from the specified file
         */
        public static EffiProzProperties getPropertiesFromFile(string path)
        {

            if (string.IsNullOrEmpty(path))
            {
                return null;
            }

            EffiProzProperties p = new EffiProzProperties(path);

            try
            {
                p.load();
            }
            catch (Exception) { }

            return p;
        }
             
        public static String[] listLocalInetAddressNames()
        {
            string hostName;         
            IPHostEntry hostEntry;
            HashSet<string> set = new HashSet<string>();

            try
            {
                hostName   = Dns.GetHostName();             
                hostEntry = Dns.GetHostEntry(String.Empty);        
         

                set.Add(hostName);
                for (int i = 0; i < hostEntry.AddressList.Length; i++)
                {
                    set.Add(hostEntry.AddressList[i].ToString());           
                }

                for (int i = 0; i < hostEntry.Aliases.Length; i++)
                {
                    set.Add(hostEntry.Aliases[i].ToString());       
                }
            }
            catch (Exception) { }          

          
            string[] addrArray = new String[set.Count];
            set.CopyTo(addrArray);
            return addrArray;
        }

        /**
         * Retrieves a new default properties object for a server of the
         * specified protocol
         *
         * @return a new default properties object
         */
        public static EffiProzProperties newDefaultProperties(int protocol)
        {

            EffiProzProperties p = new EffiProzProperties();

            p.setProperty(ServerConstants.SC_KEY_AUTORESTART_SERVER,
                          ServerConstants.SC_DEFAULT_SERVER_AUTORESTART);
            p.setProperty(ServerConstants.SC_KEY_ADDRESS, ServerConstants.SC_DEFAULT_ADDRESS);
            p.setProperty(ServerConstants.SC_KEY_NO_SYSTEM_EXIT, ServerConstants.SC_DEFAULT_NO_SYSTEM_EXIT);

            bool isTls = ServerConstants.SC_DEFAULT_TLS;

            //try  //TODOx
            //{
            //    isTls = System.getProperty("javax.net.ssl.keyStore") != null;
            //}
            //catch (Exception e) { }

            p.setProperty(ServerConstants.SC_KEY_PORT, getDefaultPort(protocol, isTls));
            p.setProperty(ServerConstants.SC_KEY_SILENT, ServerConstants.SC_DEFAULT_SILENT);
            p.setProperty(ServerConstants.SC_KEY_TLS, isTls);
            p.setProperty(ServerConstants.SC_KEY_TRACE, ServerConstants.SC_DEFAULT_TRACE);
            p.setProperty(ServerConstants.SC_KEY_WEB_DEFAULT_PAGE, ServerConstants.SC_DEFAULT_WEB_PAGE);
            p.setProperty(ServerConstants.SC_KEY_WEB_ROOT, ServerConstants.SC_DEFAULT_WEB_ROOT);

            return p;
        }

        /**
         * Translates null or zero length value for address key to the
         * special value ServerConstants.SC_DEFAULT_ADDRESS which causes
         * ServerSockets to be constructed without specifying an InetAddress.
         *
         * @param p The properties object upon which to perform the translation
         */
        public static void translateAddressProperty(EffiProzProperties p)
        {

            if (p == null)
            {
                return;
            }

            string address = p.getProperty(ServerConstants.SC_KEY_ADDRESS);

            if (string.IsNullOrEmpty(address))
            {
                p.setProperty(ServerConstants.SC_KEY_ADDRESS, ServerConstants.SC_DEFAULT_ADDRESS);
            }
        }

        /**
         * Translates the legacy default database form: database=...
         * to the 1.7.2 form: database.0=...
         *
         * @param p The properties object upon which to perform the translation
         */
        public static void translateDefaultDatabaseProperty(EffiProzProperties p)
        {

            if (p == null)
            {
                return;
            }

            if (!p.isPropertyTrue(ServerConstants.SC_KEY_REMOTE_OPEN_DB))
            {
                if (p.getProperty(ServerConstants.SC_KEY_DATABASE + "." + 0) == null)
                {
                    string defaultdb = p.getProperty(ServerConstants.SC_KEY_DATABASE);

                    if (defaultdb == null)
                    {
                        defaultdb = ServerConstants.SC_DEFAULT_DATABASE;
                    }

                    p.setProperty(ServerConstants.SC_KEY_DATABASE + ".0", defaultdb);
                    p.setProperty(ServerConstants.SC_KEY_DBNAME + ".0", "");
                }

                if (p.getProperty(ServerConstants.SC_KEY_DBNAME + "." + 0) == null)
                {
                    p.setProperty(ServerConstants.SC_KEY_DBNAME + ".0", "");
                }
            }
        }

        /**
         * Tranlates unspecified no_system_exit property to false, the default
         * typically required when a Server is started from the command line.
         *
         * @param p The properties object upon which to perform the translation
         */
        public static void translateDefaultNoSystemExitProperty(
                EffiProzProperties p)
        {

            if (p == null)
            {
                return;
            }
            p.setPropertyIfNotExists(ServerConstants.SC_KEY_NO_SYSTEM_EXIT, "false");
        }
    }
}
